package com.seedwill.common.util;

import java.sql.Types;
import java.util.Hashtable;
import java.util.Map;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

/**
 * PORT FROM APACHE Beehive UTIL

 * @author kdyi
 *
 */
public class JavaTypeHelper

{	private static Log log = LogFactory.getLog(JavaTypeHelper.class);

    private static final int TYPE_MAX = 29;
    private static final int JAVA_PRIMITIVE_TYPES = 8;
    
    @SuppressWarnings("unchecked")
	private static Map<Class, Integer> javaSQLTypeMap = new Hashtable<Class, Integer>(TYPE_MAX * 2);
    
    @SuppressWarnings("unchecked")
	private static Map<Class, Object> primitiveDefaults = new Hashtable<Class, Object>(JAVA_PRIMITIVE_TYPES);

    static {
        // Class to java.sql.Types
        javaSQLTypeMap.put(Boolean.TYPE, Types.BOOLEAN);
        javaSQLTypeMap.put(Integer.TYPE, Types.INTEGER);
        javaSQLTypeMap.put(Long.TYPE, Types.BIGINT);
        javaSQLTypeMap.put(Byte.TYPE, Types.TINYINT);
        javaSQLTypeMap.put(Short.TYPE, Types.SMALLINT);
        javaSQLTypeMap.put(Float.TYPE, Types.REAL);
        javaSQLTypeMap.put(Double.TYPE, Types.DOUBLE);
        javaSQLTypeMap.put(Boolean.class, Types.BOOLEAN);
        javaSQLTypeMap.put(Integer.class, Types.INTEGER);
        javaSQLTypeMap.put(Long.class, Types.BIGINT);
        javaSQLTypeMap.put(Byte.class, Types.TINYINT);
        javaSQLTypeMap.put(Short.class, Types.SMALLINT);
        javaSQLTypeMap.put(Float.class, Types.REAL);
        javaSQLTypeMap.put(Double.class, Types.DOUBLE);
        javaSQLTypeMap.put(String.class, Types.VARCHAR);
        javaSQLTypeMap.put(java.math.BigDecimal.class, Types.DECIMAL);
        javaSQLTypeMap.put(byte[].class, Types.VARBINARY);
        javaSQLTypeMap.put(java.sql.Timestamp.class, Types.TIMESTAMP);
        javaSQLTypeMap.put(java.sql.Time.class, Types.TIME);
        javaSQLTypeMap.put(java.sql.Date.class, Types.DATE);
        javaSQLTypeMap.put(java.sql.Ref.class, Types.REF);
        javaSQLTypeMap.put(java.sql.Blob.class, Types.BLOB);
        javaSQLTypeMap.put(java.sql.Clob.class, Types.CLOB);
        javaSQLTypeMap.put(java.sql.Array.class, Types.ARRAY);
        javaSQLTypeMap.put(java.util.Date.class, Types.TIMESTAMP);
        javaSQLTypeMap.put(java.util.Calendar.class, Types.TIMESTAMP);
        javaSQLTypeMap.put(java.util.GregorianCalendar.class, Types.TIMESTAMP);
        //javaSQLTypeMap.put(java.io.Reader.class, Types.READER);
        //javaSQLTypeMap.put(java.io.InputStream.class, Types.STREAM);

        //Java Primitive to Default values.
        primitiveDefaults.put(Boolean.TYPE, Boolean.FALSE);
        primitiveDefaults.put(Integer.TYPE, new Integer(0));
        primitiveDefaults.put(Long.TYPE, new Long(0));
        primitiveDefaults.put(Byte.TYPE, new Byte((byte)0));
        primitiveDefaults.put(Short.TYPE, new Short((short)0));
        primitiveDefaults.put(Character.TYPE, new Character('\u0000'));
        primitiveDefaults.put(Float.TYPE, new Float(0.0f));
        primitiveDefaults.put(Double.TYPE, new Double(0.0d));
    }
    
    public  static int DEFAULT_TYPE = Types.OTHER;

    public static int getSqlType(Class classType)
    {
        while (null != classType)
        {
            Integer type = (Integer)javaSQLTypeMap.get(classType);
            if (null != type)
                return type.intValue();
            classType = classType.getSuperclass();
        }
        log.warn("未找到预定义映射类型:"+classType+", 采用默认映射类型:"+DEFAULT_TYPE);
        return DEFAULT_TYPE;
    }

    public static int getSqlType(Object o)
    {
        if (null == o)
            return Types.NULL;
        return getSqlType(o.getClass());
    }

    public static Object getJaveTypeDefaultValue(Class primitiveType) {
        if (primitiveType.isPrimitive())
            return (primitiveDefaults.get(primitiveType));
        else
            return null;
    }
}
